﻿#define MIT

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DealFile;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using Common;
using BasicClass;
using DealPLC;
using DealConfigFile;
using System.Diagnostics;

#if MIT
using ACTETHERLib;
using ACTMULTILib;
#endif

namespace DealPLC
{
    public partial class LogicPLC
    {
        #region 定义
        Mutex g_MtCyc = new Mutex();
        #endregion 定义
        
        /// <summary>
        /// 循环读取线程
        /// </summary>
        public void ReadCycReg_Task()
        {
            try
            {
                ParLogicPLC.P_I.BlRead = true;

                Task task = new Task(ReadCycReg);
                task.Start();

                //监控心跳清除
                Task task1 = new Task(CycClearHeart);
                task1.Start();                

                //监控相机单线程
                SingleTaskRead();

                //触发保留监控单线程
                SingleTaskReserveTrigger();
            }
            catch (Exception ex)
            {
                Log.L_I.WriteError(NameClass, ex);
            }
        }
        /// <summary>
        /// 相机触发监控单线程
        /// </summary>
        void SingleTaskRead()
        {
            try
            {
                if (ParSetPLC.P_I.BlRSingleTaskCamera)
                {
                    new Task(TriggerCamera1).Start();
                    if (ParCameraWork.NumCamera == 1)
                    {
                        return;
                    }
                    new Task(TriggerCamera2).Start();
                    if (ParCameraWork.NumCamera == 2)
                    {
                        return;
                    }
                    new Task(TriggerCamera3).Start();
                    if (ParCameraWork.NumCamera == 3)
                    {
                        return;
                    }
                    new Task(TriggerCamera4).Start();
                    if (ParCameraWork.NumCamera == 4)
                    {
                        return;
                    }
                    new Task(TriggerCamera5).Start();
                    if (ParCameraWork.NumCamera == 5)
                    {
                        return;
                    }
                    new Task(TriggerCamera6).Start();
                    if (ParCameraWork.NumCamera == 6)
                    {
                        return;
                    }
                    new Task(TriggerCamera7).Start();
                    if (ParCameraWork.NumCamera == 7)
                    {
                        return;
                    }
                    new Task(TriggerCamera8).Start();
                }
            }
            catch (Exception ex)
            {
                Log.L_I.WriteError(NameClass, ex);
            }
        }


        #region 触发保留单线程
        /// <summary>
        /// 触发保留单线程
        /// </summary>
        void SingleTaskReserveTrigger()
        {
            try
            {
                //监控触发保留寄存器
                TaskFactory taskFactory = new TaskFactory();
                Task[] task = new Task[]
                {
                    taskFactory.StartNew(TriggerReserve1),
                    taskFactory.StartNew(TriggerReserve2),
                    taskFactory.StartNew(TriggerReserve3),
                    taskFactory.StartNew(TriggerReserve4),
                    taskFactory.StartNew(TriggerReserve5),
                    taskFactory.StartNew(TriggerReserve6),
                    taskFactory.StartNew(TriggerReserve7),
                    taskFactory.StartNew(TriggerReserve8),

                    taskFactory.StartNew(TriggerReserve9),
                    taskFactory.StartNew(TriggerReserve10),
                    taskFactory.StartNew(TriggerReserve11),
                    taskFactory.StartNew(TriggerReserve12),
                    taskFactory.StartNew(TriggerReserve13),
                    taskFactory.StartNew(TriggerReserve14),
                    taskFactory.StartNew(TriggerReserve15),
                    taskFactory.StartNew(TriggerReserve16),

                    taskFactory.StartNew(TriggerReserve17),
                    taskFactory.StartNew(TriggerReserve18),
                    taskFactory.StartNew(TriggerReserve19),
                    taskFactory.StartNew(TriggerReserve20),
                };
            }
            catch (Exception ex)
            {
                Log.L_I.WriteError(NameClass, ex);
            }
        }
        #endregion 触发保留单线程

        #region 循环读取触发信号及处理_完整版协议
        void ReadCycReg()
        {
            Thread.Sleep(3000);//延迟3s开始读数
            int[] intValue = new int[ParSetPLC.P_I.IntNumCycReg];
            //监控整个周期的时间
            //Stopwatch swPLCTrrigger = new Stopwatch();
            //swPLCTrrigger.Start();
            Stopwatch swPLC = new Stopwatch();//监控仅仅读取寄存器的时间
            swPLC.Restart();
           
            while (ParLogicPLC.P_I.BlRead)
            {                
                long timeOld = swPLC.ElapsedMilliseconds;
                Thread.Sleep(2 + ParSetPLC.P_I.Delay);//循环延迟
                g_MtCyc.WaitOne();
               
                try
                {                 
                    bool blResult = false;
                    //区分协议
                    if (ParSetPLC.P_I.TypePLCProtocol_e == TypePLCProtocol_enum.FullNew)//新版本协议，是连续地址
                    {
                        blResult = ReadBlockReg_Continue(ParSetPLC.P_I.RegCyc, ParSetPLC.P_I.IntNumCycReg, "ReadCycReg", out intValue);//批量读取寄存器
                    }
                    else
                    {
                        blResult = ReadBlockReg(ParSetPLC.P_I.RegCyc, ParSetPLC.P_I.IntNumCycReg, "ReadCycReg", out intValue);//批量读取寄存器
                    }

                    long elapse = swPLC.ElapsedMilliseconds - timeOld;//获取循环的时间
                    new Task(new Action(() =>
                        {
                            LogPLC.L_I.WritePLC("PLCReadCycRegTime", elapse.ToString() + "--Delay:" + ParSetPLC.P_I.Delay.ToString());//将时间记录到本地
                        })).Start();

                    if (blResult || ComValue.C_I.blTrrigerPLC)
                    {
                        try
                        {
                            #region 记录数据
                            string str = "";
                            for (int i = 1; i < ParSetPLC.P_I.IntNumCycReg; i++)
                            {
                                str += intValue[i].ToString().PadRight(12, ' ');
                            }
                            if (ParLogicPLC.P_I.strOldCycRead != str)
                            {
                                //当数据发生变化时，开始记录
                                CheckReg.C_I.AddValue(intValue);
                                if (RefreshRegValue_event != null)
                                {
                                    RefreshRegValue_event();
                                }

                                string[] strReg = ParSetPLC.P_I.RegCyc.Split('\n');
                                string regLog = "";
                                for (int i = 1; i < strReg.Length; i++)
                                {
                                    regLog += strReg[i].PadRight(12, ' ');
                                }
                                ParLogicPLC.P_I.strOldCycRead = str;
                                new Task(new Action(() =>
                                    {
                                        LogPLC.L_I.WritePLC("PLCCycRead", regLog, str);
                                    })).Start();

                            }
                            #endregion 记录数据

                            if (ParSetPLC.P_I.TypePLCProtocol_e == TypePLCProtocol_enum.FullNew)//精简版本协议
                            {
                                DealTrrigerSingle_New(intValue);
                            }
                            else
                            {
                                //传入寄存器值，处理触发
                                DealTrrigerSingle(intValue);
                            }
                        }
                        catch (Exception ex)
                        {
                            Thread.Sleep(5000);
                            Log.L_I.WriteError("LogicPLC", ex);
                        }
                    }
                    else
                    {
                        CommunicationState_event("循环读取PLC监控寄存器失败！", "red");
                        Thread.Sleep(2000);                        
                        Log.L_I.WriteError("LogicPLC", "循环读取PLC监控寄存器失败");
                    }
                }
                catch (Exception ex)
                {
                    Thread.Sleep(5000);
                    Log.L_I.WriteError("LogicPLC", ex);
                }
                finally
                {
                    g_MtCyc.ReleaseMutex();
                    //swPLCTrrigger.Stop();
                    //LogPLC.L_I.WritePLC(NameClass, swPLCTrrigger.ElapsedMilliseconds.ToString());//将时间记录到本地
                }
            }
        }
        #endregion 循环读取触发信号及处理_完整版协议

        #region 清空触发信号
        void ClearTrigger()
        {
            try
            {
                Thread.Sleep(300);
                int[] intValue = new int[RegMonitor.R_I.NumTrigger];
                string reg = "";
                for (int i = 0; i < RegMonitor.R_I.NumTrigger; i++)
                {
                    reg += RegMonitor.R_I[i].NameReg;
                }
                bool blResult = WriteBlockReg(reg, RegMonitor.R_I.NumTrigger, intValue, "ClearTrigger");
                if (blResult)
                {
                    return;
                }
                CommunicationState_event("清空寄存器失败:", "red");
            }
            catch (Exception ex)
            {
                Log.L_I.WriteError("LogicPLC", ex);
            }
        }
        #endregion 清空触发信号

    }
}
